#!/usr/bin/env python
import urllib2,urllib
import time
try:
  import json
except ImportError:
  import simplejson as json
class SaltAPI(object):
  __token_id = ''
  def __init__(self,url,username,password):
    self.__url = url.rstrip('/')
    self.__user = username
    self.__password = password
  def token_id(self):
    ''' user login and get token id '''
    params = {'eauth': 'pam', 'username': self.__user, 'password': self.__password}
    encode = urllib.urlencode(params)
    obj = urllib.unquote(encode)
    content = self.postRequest(obj,prefix='/login')
    try:
      self.__token_id = content['return'][0]['token']
    except KeyError:
      raise KeyError
  def postRequest(self,obj,prefix='/'):
    url = self.__url + prefix
    headers = {'X-Auth-Token'   : self.__token_id}
    req = urllib2.Request(url, obj, headers)
    opener = urllib2.urlopen(req)
    content = json.loads(opener.read())
    return content
  def list_all_key(self):
    params = {'client': 'wheel', 'fun': 'key.list_all'}
    obj = urllib.urlencode(params)
    self.token_id()
    content = self.postRequest(obj)
    minions = content['return'][0]['data']['return']['minions']
    minions_pre = content['return'][0]['data']['return']['minions_pre']
    return minions,minions_pre
  def delete_key(self,node_name):
    params = {'client': 'wheel', 'fun': 'key.delete', 'match': node_name}
    obj = urllib.urlencode(params)
    self.token_id()
    content = self.postRequest(obj)
    ret = content['return'][0]['data']['success']
    return ret
  def accept_key(self,node_name):
    params = {'client': 'wheel', 'fun': 'key.accept', 'match': node_name}
    obj = urllib.urlencode(params)
    self.token_id()
    content = self.postRequest(obj)
    ret = content['return'][0]['data']['success']
    return ret
  def remote_noarg_execution(self,tgt,fun):
    ''' Execute commands without parameters '''
    params = {'client': 'local', 'tgt': tgt, 'fun': fun}
    obj = urllib.urlencode(params)
    self.token_id()
    content = self.postRequest(obj)
    ret = content['return'][0][tgt]
    return ret
  def remote_execution(self,tgt,fun,arg):
    ''' Command execution with parameters '''		
    params = {'client': 'local', 'tgt': tgt, 'fun': fun, 'arg': arg}
    obj = urllib.urlencode(params)
    self.token_id()
    content = self.postRequest(obj)
    ret = content['return'][0][tgt]
    return ret

  def target_remote_execution(self,tgt,fun,arg):
    ''' Use targeting for remote execution '''
    params = {'client': 'local', 'tgt': tgt, 'fun': fun, 'arg': arg, 'expr_form': 'nodegroup'}
    obj = urllib.urlencode(params)
    self.token_id()
    content = self.postRequest(obj)
    jid = content['return'][0]['jid']
    return jid
  def deploy(self,tgt,arg):
    ''' Module deployment '''
    params = {'client': 'local', 'tgt': tgt, 'fun': 'state.sls', 'arg': arg}
    obj = urllib.urlencode(params)
    self.token_id()
    content = self.postRequest(obj)
    return content
  def async_deploy(self,tgt,arg):
    ''' Asynchronously send a command to connected minions '''
    params = {'client': 'local_async', 'tgt': tgt, 'fun': 'state.sls', 'arg': arg}
    obj = urllib.urlencode(params)
    self.token_id()
    content = self.postRequest(obj)
    jid = content['return'][0]['jid']
    return jid
  def target_deploy(self,tgt,arg):
    ''' Based on the node group forms deployment '''
    params = {'client': 'local_async', 'tgt': tgt, 'fun': 'state.sls', 'arg': arg, 'expr_form': 'nodegroup'}
    obj = urllib.urlencode(params)
    self.token_id()
    content = self.postRequest(obj)
    jid = content['return'][0]['jid']
    return jid

def main():
    import json
    
    sapi = SaltAPI(url='https://192.168.8.13:8000',username='jc',password='123456')
    print sapi.list_all_key()


    #sapi.token_id()
    #sapi.delete_key('test-01')
    #print sapi.accept_key('local_ubuntu')
    print sapi.accept_key('vm-win7-01')

    #sapi.deploy('test-01','nginx')
    #print sapi.remote_noarg_execution('test-01','grains.items')
    #print sapi.remote_noarg_execution('local_ubuntu','test.ping')
    #print sapi.remote_noarg_execution('jxm-pc-windows','test.ping')
    #print sapi.remote_noarg_execution('jxm-pc-windows','mcpServerConfig_module.get_config_info')

    # read config info
    print sapi.remote_execution('vm-win7-01','mcpServerConfig_module.get_config_info','C:\\config.ini')

    # change config info
    print sapi.remote_execution('vm-win7-01','mcpServerConfig_module.change_config_info_json',json.dumps({"key":"Model","value":"-- hello salt world --","configPath":'C:\\tmp\\config.ini'}))

if __name__ == '__main__':
    main()
